package com.example.springdatajpa.service;

import com.example.springdatajpa.dao.*;
import com.example.springdatajpa.entity.Order;
import com.sun.tools.corba.se.idl.constExpr.Or;
import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.test.annotation.Rollback;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.List;

@Service
public class OrderService {
    @Autowired
    private OrderDao orderDao;//基本Dao
    @Autowired
    private DaoCrudRepository crudRepository;//CrudDao
    @Autowired
    private MyPagingAndSortingRepository myPagingAndSortingRepository;//PageDao
    @Autowired
    private OrderSpecificationExecutor orderSpecificationExecutor;
    @Autowired
    private MyOrderDaoImpl myOrderDao;


    public void sava(Order order){
        orderDao.save(order);
    }

    public List<Order> findByNoteIs(String str){
        return orderDao.findByNoteIs(str);
    }

    public List<Order> queryOrderByNoteUseJPQL(String name,Long id){
        return orderDao.queryOrderByNoteUseJPQL(name,id);
    }

    public List<Order>queryOrderByNoteUseSQL(String note,Long id){
        System.out.println(note);
        return orderDao.queryOrderByNoteUseSQL(note,id);
    }

    @Transactional
    @Rollback(false)
    public void updateUseById(String note,Long id){
        orderDao.updateUseById(note,id);
    }


    public void save(Order order){
        crudRepository.save(order);
    }

    public void saveByList(List<Order> orders){
    }

    /**
     * 翻页查询 利用翻页插件Pageable、PageRequst
     * @param page
     * @param size
     * @return
     */
    public Page<Order> page1(int page,int size){
        Pageable pageable = PageRequest.of(page,size);
        Page<Order> p = myPagingAndSortingRepository.findAll(pageable);
        return p;
    }

    /**
     * 排序查询 利用Sort.by
     * @return
     */
    public List<Order> findSort(){
        return (List<Order>) myPagingAndSortingRepository.findAll(Sort.by(Sort.Direction.DESC,"id"));
    }

    /**
     * 多条件排序查询
     * @return
     */
    public List<Order>findMoreSort(){
        Sort.Order order = new Sort.Order(Sort.Direction.ASC,"id");
        Sort.Order order2 = new Sort.Order(Sort.Direction.DESC,"userId");
        Sort.Order order3 = new Sort.Order(Sort.Direction.DESC,"addrId");

        Sort sort = Sort.by(order,order2,order3);

        return (List<Order>) myPagingAndSortingRepository.findAll(sort);
    }

    /**
     * 根据 JPA 条件查询器查询 给定条件查询
     * @return
     */
    public List<Order> findBySpecification(){
        Specification<Order> specification = new Specification<Order>() {
            @Override
            public Predicate toPredicate(Root<Order> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                Predicate restrication = criteriaBuilder.equal(root.get("note"),"测试4");
                return restrication;
            }
        };
        return orderSpecificationExecutor.findAll(specification);
    }

    /**
     * JPA给定条件查询 多条件
     * @return
     */
    public List<Order> findBySpecificationMore(){
        Specification<Order> specification = new Specification<Order>() {
            @Override
            public Predicate toPredicate(Root<Order> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                return criteriaBuilder.or(criteriaBuilder.equal(root.get("note"),"测试4"),
                        criteriaBuilder.equal(root.get("statuId"),4));
            }
        };
        return orderSpecificationExecutor.findAll(specification);
    }

    /**
     * 利用 条件查询器 specification + 翻页工具 Pageable+PageRequst 条件+翻页查询
     * @return
     */
    public List<Order> findByPage(){
        Specification<Order> specification = new Specification<Order>() {
            @Override
            public Predicate toPredicate(Root<Order> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                return criteriaBuilder.equal(root.get("userId"),1214893165627064322L);
            }
        };

        Pageable pageable = PageRequest.of(0,1);
        return orderSpecificationExecutor.findAll(specification,pageable).getContent();
    }

    /**
     *
     * @return 根据条件和排序查询
     */
    public List<Order>findBySortBySpecification(){
        Specification<Order> specification = new Specification<Order>() {
            @Override
            public Predicate toPredicate(Root<Order> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                return criteriaBuilder.equal(root.get("userId"),1214893165627064322L);
            }
        };
        Sort sort = Sort.by(Sort.Direction.DESC,"id");
        return orderSpecificationExecutor.findAll(specification,sort);
    }

    /**
     * 根据条件查询器 排序、分页查询
     * @return
     */
    public List<Order>findBySortPageBySpecification(){
        Specification<Order> specification = new Specification<Order>() {
            @Override
            public Predicate toPredicate(Root<Order> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                return criteriaBuilder.equal(root.get("userId"),1214893165627064322L);
            }

        };

        Sort sort = Sort.by(Sort.Direction.DESC,"id");
        Pageable pageable = PageRequest.of(0,2,sort);
        return orderSpecificationExecutor.findAll(specification,pageable).getContent();
    }


    public Order findOrderByMyReposity(Long id){
        System.out.println(myOrderDao.findOrderById(id).toString());
        return myOrderDao.findOrderById(id);
    }

}
